<!--
 * @Description: 
 * @version: 
 * @Author: 尹鹏孝
 * @Date: 2022-01-04 11:18:23
 * @LastEditors: 尹鹏孝
 * @LastEditTime: 2022-01-05 10:11:19
-->
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>螺旋矩阵</title>
</head>

<body>
    <script>
        // 螺旋矩阵输入3输出：[ [ 1, 2, 3 ], [ 8, 9, 4 ], [ 7, 6, 5 ] ]

        // 输入4：[[1, 2, 3, 4], [12, 13, 14, 5], [11, 16, 15, 6], [10, 9, 8, 7]]
        // 思路：坚持循环不变量原则
        // 顺序是：
        // 填充上行从左到右
        //     填充右列从上到下
        //     填充下行从右到左
        //     填充左列从下到上
        // =>  这里一圈下来，我们要画每四条边，这四条边怎么画，每画一条边都要坚持一致的左闭右开，或者左开又闭的原则，这样这一圈才能按照统一的规则画下来

        var generateMatrix = function (n) {

            let startX = startY = 0;   // 起始位置
            let loop = Math.floor(n / 2);   // 旋转圈数
            let mid = Math.floor(n / 2);    // 中间位置
            let offset = 1;    // 控制每一层填充元素个数
            let count = 1;     // 更新填充数字
            let res = new Array(n).fill(0).map(() => new Array(n).fill(0));

            while (loop--) {
                let i, j;
                i = startX;
                j = startY;
                // 模拟填充上行从左到右(左闭右开)
                for (; j < startY + n - offset; j++) {
                    res[i][j] = count++;
                }
                // 模拟填充上行从左到右(左闭右开)
                for (; i < startX + n - offset; i++) {
                    res[i][j] = count++;
                }
                // 模拟填充下行从右到左(左闭右开)
                for (; j > startY; j--) {
                    res[i][j] = count++;
                }
                // 模拟填充左列从下到上(左闭右开)
                for (; i > startX; i--) {
                    res[i][j] = count++;
                }

                // 第二圈开始的时候，起始位置要各自加1， 例如：第一圈起始位置是(0, 0)，第二圈起始位置是(1, 1)
                startX++;
                startY++;

                // offset 控制每一圈里每一条边遍历的长度
                offset += 2;
            }

            // 如果n为奇数的话，需要单独给矩阵最中间的位置赋值
            if (n % 2 === 1) {
                res[mid][mid] = count;
            }
            return res;
        }


        let six = generateMatrix(6);
        console.log(six);
        let five = generateMatrix(5);
        console.log(five);


    </script>

</body>

</html>